package com.pactera.madp.cp.service.sync.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.pactera.madp.cp.api.dto.sync.SaLoginDTO;
import com.pactera.madp.cp.api.dto.sync.SaQueryDTO;
import com.pactera.madp.cp.api.entity.sync.MaTotalDataBoardEntity;
import com.pactera.madp.cp.api.entity.sync.SyncEventEntity;
import com.pactera.madp.cp.api.vo.sync.SaEventVO;
import com.pactera.madp.cp.api.vo.sync.SaTokenVO;
import com.pactera.madp.cp.client.SaClient;
import com.pactera.madp.cp.config.SaConfig;
import com.pactera.madp.cp.service.sync.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 神策平台-请求神策API-服务接口实现
 * @date 2022-05-11
 * @author Deming.Chang
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SaClientServiceImpl implements SaClientService {

    /**
     * 神策接口调用实现类
     */
    private final SaClient client;
    /**
     * 神策平台配置类
     */
    private final SaConfig config;

    @Override
    public List<SyncEventEntity> getSaEvents(Long lastMaxReceiveTime) {
        String sql = StrUtil.replace(SA_EVENTS_SQL, SA_PLACEHOLDER, String.valueOf(lastMaxReceiveTime));
        log.info("--->Ma events sql: {}", sql);

        SaQueryDTO dto = new SaQueryDTO();
        dto.setQ(sql).setFormat(SA_RESULT_JSON);

        String events = client.query(this.getSaToken(), config.getProject(), dto);
        List<SyncEventEntity> eventList = new ArrayList<>();
        StrUtil.split(events, StrUtil.C_LF).forEach(event -> {
            if(StrUtil.isNotBlank(event)){
                SaEventVO vo = JSONUtil.toBean(event, SaEventVO.class);
                eventList.add(this.voToEntity(vo));
            }
        });
        return  eventList;
    }

    @Override
    public List<MaTotalDataBoardEntity> getSaDataBoardTotals() {
        log.info("--->Ma events sql: {}", SA_TOTALS_SQL);

        SaQueryDTO dto = new SaQueryDTO();
        dto.setQ(SA_TOTALS_SQL)
                .setFormat(SA_RESULT_JSON);

        String totals = client.query(this.getSaToken(), config.getProject(), dto);
        List<MaTotalDataBoardEntity> dataBoardList = new ArrayList<>();
        StrUtil.split(totals, StrUtil.C_LF).forEach(total -> {
            if(StrUtil.isNotBlank(total)){
                dataBoardList.add(JSONUtil.toBean(total, MaTotalDataBoardEntity.class));
            }
        });
        return dataBoardList;
    }

    /**
     * 获取神策平台账号凭证
     * 神策平台账号凭证默认30分钟有效
     * @return 返回神策平台账号凭证
     */
    private String getSaToken() {
        SaLoginDTO dto = new SaLoginDTO();
        dto.setAccount_name(config.getAccountName())
                .setPassword(config.getPassword());
        SaTokenVO token = client.login(String.valueOf(true), config.getProject(), dto);
        if (ObjectUtil.isNotNull(token)) {
            return token.getSession_id();
        }
        return null;
    }

    /**
     * 将VO对象转换为Entity对象
     * @param vo    待转换对象
     * @return      转换后对象
     */
    private SyncEventEntity voToEntity(SaEventVO vo){
        SyncEventEntity entity = new SyncEventEntity();
        entity.setEvent(vo.getEvent())
                .setDate(vo.getDate())
                .setTime(vo.getTime())
                .setUserId(vo.getUserId())
                .setDistinctId(vo.getDistinctId())
                .setRecommendId(vo.getRecommendId())
                .setReceiveTime(vo.get$receiveTime())
                .setTrackSignupOriginalId(vo.get$trackSignupOriginalId())
                .setOs(vo.get$os())
                .setOsVersion(vo.get$osVersion())
                .setModel(vo.get$model())
                .setManufacturer(vo.get$manufacturer())
                .setCarrier(vo.get$carrier())
                .setWifi(vo.get$wifi())
                .setNetworkType(vo.get$networkType())
                .setBrowser(vo.get$browser())
                .setBrowserVersion(vo.get$browserVersion())
                .setScreenWidth(vo.get$screenWidth())
                .setScreenHeight(vo.get$screenHeight())
                .setViewportPosition(vo.get$viewportPosition())
                .setViewportWidth(vo.get$viewportWidth())
                .setViewportHeight(vo.get$viewportHeight())
                .setLib(vo.get$lib())
                .setDeviceId(vo.get$deviceId())
                .setAppVersion(vo.get$appVersion())
                .setAppId(vo.get$appId())
                .setAppName(vo.get$appName())
                .setTimezoneOffset(vo.get$timezoneOffset())
                .setUrl(vo.get$url())
                .setUrlPath(vo.get$urlPath())
                .setUrlHost(vo.get$urlHost())
                .setReferrer(vo.get$referrer())
                .setReferrerHost(vo.get$referrerHost())
                .setScreenName(vo.get$screenName())
                .setTitle(vo.get$title())
                .setIsFirstDay(vo.get$isFirstDay())
                .setIsFirstTime(vo.get$isFirstTime())
                .setIp(vo.get$ip())
                .setCity(vo.get$city())
                .setProvince(vo.get$province())
                .setCountry(vo.get$country())
                .setEventDuration(vo.get$eventDuration())
                .setLatestTrafficSourceType(vo.get$latestTrafficSourceType())
                .setLatestReferrer(vo.get$latestReferrer())
                .setLatestSearchKeyword(vo.get$latestSearchKeyword())
                .setFinancialType(vo.getFinancialType())
                .setFinancialCode(vo.getFinancialCode())
                .setFinancialName(vo.getFinancialName())
                .setBuyPeriod(vo.getBuyPeriod())
                .setDepositType(vo.getDepositType())
                .setDepositNumber(vo.getDepositNumber())
                .setDepositName(vo.getDepositName())
                .setLoanType(vo.getLoanType())
                .setLoanCode(vo.getLoanCode())
                .setLoanName(vo.getLoanName())
                .setCreditType(vo.getCreditType())
                .setCreditCode(vo.getCreditCode())
                .setCreditName(vo.getCreditName())
                .setActivityType(vo.getActivityType())
                .setActivityCode(vo.getActivityCode())
                .setActivityEntranceType(vo.getActivityEntranceType())
                .setActivityName(vo.getActivityName())
                .setInfoType(vo.getInfoType())
                .setInfoSubType(vo.getInfoSubType())
                .setInfoNumber(vo.getInfoNumber())
                .setInfoName(vo.getInfoName())
                .setInfoSource(vo.getInfoSource());
        return entity;
    }

}
